/**
 * Copyright (C), -2025, www.bosssof.com.cn
 * @FileName RoleServiceImpl.java
 * @Author Administrator
 * @Date 2022-9-30  16:25
 * @Description 包含角色管理界面的功能实现
 * History:
 * <author> Administrator
 * <time> 2022-9-30  16:25
 * <version> 1.0.0
 * <desc> abel.zhan 优化代码结构 分配用户方法采用清除用户角色重新分配，优化角色的多资源分配方式 优化代码结构和效率改为批量插入
 */
package com.sd365.permission.centre.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.sd365.common.core.annotation.mybatis.Pagination;
import com.sd365.common.core.annotation.stuffer.CommonFieldStuffer;
import com.sd365.common.core.annotation.stuffer.IdGenerator;
import com.sd365.common.core.annotation.stuffer.MethodTypeEnum;
import com.sd365.common.core.common.advice.MyPageInfo;
import com.sd365.common.core.common.api.CommonPage;
import com.sd365.common.core.common.constant.EntityConsts;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.common.exception.DaoException;
import com.sd365.common.core.common.exception.code.BizErrorCode;
import com.sd365.common.core.common.exception.code.CommonErrorCode;
import com.sd365.common.core.common.pojo.entity.TenantBaseEntity;
import com.sd365.common.core.common.service.AbstractBusinessService;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.util.BeanException;
import com.sd365.common.util.BeanUtil;
import com.sd365.permission.centre.dao.mapper.*;
import com.sd365.permission.centre.entity.*;
import com.sd365.permission.centre.pojo.dto.*;
import com.sd365.permission.centre.pojo.query.RoleQuery;
import com.sd365.permission.centre.pojo.query.UserQuery;
import com.sd365.permission.centre.pojo.vo.RoleCompanyVO;
import com.sd365.permission.centre.service.RoleService;
import com.sd365.permission.centre.service.cache.IRoleCache;
import com.sd365.permission.centre.service.config.Global;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import tk.mybatis.mapper.entity.Example;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Class RoleServiceImpl
 * @Description able.zhan 2022-09-30 重构了 人员分配，如果该类触发校验异常或者业务异常将由统一异常处理
 * 包含注意方法：1 初始化角色和缓存关系用于网关鉴权提速 2 为角色分配权限 3 为角色分配用户
 * 2023-4-20 1 优化了插入效率改为批量更新  2  角色重新分配的时候优化缓存
 * @Author Administrator
 * @Date 2022-9-30  16:24
 * @version 1.0.0
 */
@Service
@Slf4j
public class RoleServiceImpl extends AbstractBusinessService implements RoleService {
    /**
     * 角色缓存操作类
     */
    @Autowired
    private IRoleCache roleCache;

    /**
     * redis 操作类用于将角色的资源存储到redis
     */
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    /**
     *  角色mapper
     */
    @Autowired
    private RoleMapper roleMapper;

    /**
     *  角色资源mapper 对应basic_role_resource表
     */
    @Autowired
    private RoleResourceMapper roleResourceMapper;

    /**
     *  角色所处公司查询，一个角色可以属于多个公司
     */
    @Autowired
    private RoleCompanyMapper roleCompanyMapper;
    /**
     * 用户角色查询 对应 basic_user_role表
     */
    @Autowired
    private UserRoleMapper userRoleMapper;

    /**
     *  用户mapper
     */
    @Autowired
    private UserMapper userMapper;

    /**
     * id 生成器
     */
    @Autowired
    private IdGenerator idGenerator;

    /**
     * 资源mapper
     */
    @Autowired
    private ResourceMapper resourceMapper;

    /**
     * 职位mapper
     */
    @Autowired
    private PositionMapper positionMapper;

    /**
     * 公司mapper
     */
    @Autowired
    private CompanyMapper companyMapper;

    /**
     * 部门mapper
     */
    @Autowired
    private DepartmentMapper departmentMapper;

    @Override
    public Boolean loadRoleResource2Cache(@NotNull  Role role) {
        List<Role> roles = roleMapper.commonQuery(role);
        if (CollectionUtils.isEmpty(roles)){ throw new BusinessException(BizErrorCode.DATA_SEARCH_NOT_FOUND,"没有找到对应的角色");}
        // TODO 这里效率太差了需要优化，否则启动加载到内存过程比较慢 修改为where roleId in (...)
        for (Role role1 : roles) {
            // 查询获得 resourceList
            Example example=new Example(RoleResource.class);
            example.createCriteria().andEqualTo("roleId",role1.getId());
            // 查询某一个角色的资源列表，这里查询会有点慢好在角色数量不多 考虑优化where in 查询
            List<RoleResource> roleResourceList = roleResourceMapper.selectByExample(example);
            if(CollectionUtils.isEmpty(roleResourceList)){
                continue;
            }
            /**
             * 每个角色 定义为一个 hashmap对象放在 redis ， hash对象在内存中的key为
             * Global.HASH_ROLE_ID_KEY+role1.getId(),  hashmap 的key为 RoleResource的id
             * value为 RoleResource对象
             */
            roleCache.cacheRoleResource(role1,roleResourceList);
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean assignResource(@NotNull @Valid RoleResourceDTO roleResourceDTO) {
        // 给多个角色分配多个资源 参数去重复
        Set<Long> roleIdSet=roleResourceDTO.getRoleIds().stream().collect(Collectors.toSet());
        List<Long> roleIds =CollectionUtils.arrayToList(roleIdSet.toArray());
        Set<Long> resourceSet= roleResourceDTO.getResourceIds().stream().collect(Collectors.toSet());
        List<Long> resourceIds = CollectionUtils.arrayToList(resourceSet.toArray());
        /***
         *  业务逻辑思考：
         *   1 进行角色分配 优先采用先删除后插入的策略  放弃 逐条更新以及比较删除策略，因为代码复杂
         *   2 调用 批量删除角色资源方法 removeRolesResources
         *   3 调用 批量插入角色和资源关系方法 batchInsertRolesResources
         *   4 将新的角色和资源的关系更新到缓存 ，注意是否存在并发
         *  考虑异常点：
         *  1 删除的同时是否有人在访问
         *  2 更新缓存的时候 是否有人在访问缓存
         */
        // 删除原来的角色资源
        removeRolesResources(roleIds);
        // 批量插入行的角色
        boolean result=batchInsertRolesResources(roleIds,resourceIds);
        // 开始重置缓存
        List<Role> roleList=new ArrayList<>();
        roleIds.stream().forEach(id->{
            Role role=new Role();
            role.setId(id);
            roleList.add(role);
        });
        roleCache.cachedMultiRolesResrouces(roleList);
        return result;
    }

    @Override
    public Boolean assignUser(UserRoleDTO userRoleDTO) {
        //给多个角色分配多个资源 如果重复要去除
        List<Long> roleIds =CollectionUtils.arrayToList(userRoleDTO.getRoleIds().stream().collect(Collectors.toSet()).toArray());
        List<Long> userIds =CollectionUtils.arrayToList( userRoleDTO.getUserIds().stream().collect(Collectors.toSet()).toArray());
        // 删除原来的角色所对用的用户
        Example example=new Example(UserRole.class);
        example.createCriteria().andIn("roleId",roleIds);
        int deletedRows=userRoleMapper.deleteByExample(example);

        // 插入角色所包含的新用户
        int insertRows=0;
        for (Long roleId : roleIds) {
            UserRole userRole = new UserRole();
            userRole.setRoleId(roleId);
            // 逐个插入用户，用户不多此操作无大影响
            for (Long userId : userIds) {
                userRole.setId(idGenerator.snowflakeId());
                userRole.setUserId(userId);
                userRole.setStatus((byte) EntityConsts.INITIAL_STATUS);
                userRole.setVersion(EntityConsts.INITIAL_VERSION);
                // 公用字段补充未来直接myabtis插件填写
                super.baseDataStuff4Add(userRole);
                super.baseDataStuffCommonPros(userRole);
                insertRows += userRoleMapper.insert(userRole);
            }
        }
        return insertRows>0;
    }

    @Override
    public List<Node> queryResourceByRoleId(long roleId) {

        return roleResourceMapper.queryResourceByRoleId(roleId);
    }

    @Override
    public List<Node> selectCompany() {
        return roleMapper.selectCompany();
    }

    @Override
    public boolean haveRole(@Valid RoleDTO roleDTO) {
        Role role = BeanUtil.copy(roleDTO, Role.class);
        return roleMapper.haveRole(role) > 0;
    }

    @Override
    @CommonFieldStuffer(methodType = MethodTypeEnum.ADD)
    public Boolean add(@Valid RoleDTO roleDTO) {
        Role role = BeanUtil.copy(roleDTO, Role.class);
        role.setId(idGenerator.snowflakeId());
        // 加入一条空资源避免删除的时候么有对应的缓存而出错
        List<RoleResource> roleResourceList=new ArrayList<>();
        RoleResource roleResource=new RoleResource();
        roleResource.setId(idGenerator.snowflakeId());
        roleResourceList.add(roleResource);
        roleCache.cacheRoleResource(role,roleResourceList);

        return roleMapper.insert(role) > 0;
    }

    @Transactional
    @Override
    public Boolean remove(Long id, Long version) {
        Example exampleRole = new Example(Role.class);
        exampleRole.createCriteria().andEqualTo("id", id);

        Example exampleRoleResource = new Example(RoleResource.class);
        exampleRoleResource.createCriteria().andEqualTo("roleId", id);

        Example exampleUserRole = new Example(UserRole.class);
        exampleUserRole.createCriteria().andEqualTo("roleId", id);

        roleResourceMapper.deleteByExample(exampleRoleResource);
        userRoleMapper.deleteByExample(exampleUserRole);
        boolean result=roleMapper.deleteByExample(exampleRole) > 0;
        if(result){
          // 移除缓存中的角色和资源管理
          roleCache.removeCacheRoleResources(id);
        }
        return result;
    }


    @Override
    @CommonFieldStuffer(methodType = MethodTypeEnum.UPDATE)
    public RoleDTO modify(RoleDTO roleDTO) {
        Role role =roleMapper.selectById(roleDTO.getId());
        role.setUpdatedTime(new Date());
        role = BeanUtil.copy(roleDTO, Role.class);

        BeanUtil.copy(roleDTO,role);

//        if (roleMapper.updateByExampleSelective(role, example) > 0) {
//            RoleDTO roleDTOCache = BeanUtil.copy(role, RoleDTO.class);
//            BeanUtil.copy(role.getCompany(), roleDTOCache.getCompanyDTO(), CompanyDTO.class);
//            BeanUtil.copy(role.getOrganization(), roleDTOCache.getOrganizationDTO(), OrganizationDTO.class);
//            BeanUtil.copy(role.getTenant(), roleDTOCache.getTenantDTO(), TenantDTO.class);
//            return roleDTOCache;
//        }

        if (roleMapper.updateByPrimaryKey(role) > 0) {
            RoleDTO roleDTOCache = BeanUtil.copy(role, RoleDTO.class);
            BeanUtil.copy(role.getCompany(), roleDTOCache.getCompanyDTO(), CompanyDTO.class);
            BeanUtil.copy(role.getOrganization(), roleDTOCache.getOrganizationDTO(), OrganizationDTO.class);
            BeanUtil.copy(role.getTenant(), roleDTOCache.getTenantDTO(), TenantDTO.class);
            return roleDTOCache;
        }
        return new RoleDTO();

    }
    // 开启分页的注解 分页注解一个用 common 1.3.1 包的新特性
    @Pagination
    @CommonFieldStuffer(methodType = MethodTypeEnum.QUERY)
    @Override
    public CommonPage<RoleDTO> commonQuery(@NotNull RoleQuery roleQuery) {

        Role role = new Role();
            BeanUtil.copy(roleQuery,role);
            // 因为分页插入应用的原因 这里返回的类型为 Page ，class Page extends ArrayList
            Page<Role> roles = (Page<Role>) roleMapper.commonQuery(role);
            //对象转化 po list to dto list
            List<RoleDTO> roleDTOList= BeanUtil.copyList(roles, RoleDTO.class, new BeanUtil.CopyCallback() {
                @Override
                public void copy(Object o, Object o1) {
                    // 调用 BeanUtil.copyProperties
                    if (o == null || o1 == null) {
                        throw new BeanException("拷贝对象不可以为空", new Exception("copyList 拷贝回调错误"));
                    }

                    Role roleSource = (Role) o;
                    RoleDTO roleDTO = (RoleDTO) o1;
                    BeanUtil.copy(roleSource.getCompany(), roleDTO.getCompanyDTO(), CompanyDTO.class);
                    BeanUtil.copy(roleSource.getOrganization(), roleDTO.getOrganizationDTO(), OrganizationDTO.class);
                    BeanUtil.copy(roleSource.getTenant(), roleDTO.getTenantDTO(), TenantDTO.class);
                }
            });

            return cast2CommonPage(roles,roleDTOList);
    }

    @Override
    public RoleDTO queryById(Long id) {
            RoleDTO roleDTO = null;
            Role role = roleMapper.selectById(id);
            if (role != null) {
                roleDTO = BeanUtil.copy(role, RoleDTO.class);
                BeanUtil.copy(role.getCompany(), roleDTO.getCompanyDTO(), CompanyDTO.class);
                BeanUtil.copy(role.getOrganization(), roleDTO.getOrganizationDTO(), OrganizationDTO.class);
                BeanUtil.copy(role.getTenant(), roleDTO.getTenantDTO(), TenantDTO.class);
            }
            return roleDTO;

    }

    @Override
    public RoleDTO copy(Long id) {
        Role role = roleMapper.selectByPrimaryKey(id);
        return role!=null ? BeanUtil.copy(role, RoleDTO.class) : new RoleDTO();
    }

    @Override
    @CommonFieldStuffer(methodType = MethodTypeEnum.DELETE)
    public Boolean batchRemove(@NotEmpty @Valid RoleDTO[] roleDTOS) {
        // 先删除角色关系然后删除角色 前端需要询问是否确定删除
        for (RoleDTO roleDTO : roleDTOS) {
            Example exampleRoleResource = new Example(RoleResource.class);
            exampleRoleResource.createCriteria().andEqualTo("roleId", roleDTO.getId());
            roleResourceMapper.deleteByExample(exampleRoleResource);
            Example exampleUserRole = new Example(UserRole.class);
            exampleUserRole.createCriteria().andEqualTo("roleId", roleDTO.getId());
            userRoleMapper.deleteByExample(exampleUserRole);
        }
        for (RoleDTO roleDTO : roleDTOS) {
            Example example = new Example(Role.class);
            example.createCriteria().andEqualTo("id", roleDTO.getId()).andEqualTo("version", roleDTO.getVersion());
            int result = roleMapper.deleteByExample(example);
            Assert.isTrue(result > 0, String.format("删除的记录id %d 没有匹配到版本", roleDTO.getId()));
            // 移除 role的对应资源缓存 如果异常redis如何恢复是一个问题 TODO 这里需要优化解决，如果失败redis重复操作3次还是
            //失败则记录执行失败表发出警告邮件，定期任务执行扫描没有完成任务
            roleCache.removeCacheRoleResources(roleDTO.getId());
        }

        return true;
    }

    @Pagination
    @Override
    public CommonPage<UserDTO> commonQueryUser(@NotNull UserQuery userQuery) {
        Example example = new Example(User.class);
        example.setOrderByClause("updated_time DESC");
        Example.Criteria criteria = example.createCriteria();
        if (userQuery.getCode() != null) {//模糊查询
            criteria.orLike("code", "%" + userQuery.getCode() + "%");
        } else {
            criteria.orLike("code", userQuery.getCode());
        }
        if (userQuery.getName() != null) {//模糊查询
            criteria.orLike("name", "%" + userQuery.getName() + "%");
        } else {
            criteria.orLike("name", userQuery.getName());
        }
        // 因为注解了 @Pagination应用了分页技术
        Page<User> users =(Page)userMapper.selectByExample(example);

        List<UserDTO> userDTOS = BeanUtil.copyList(users, UserDTO.class);
        if (!CollectionUtils.isEmpty(userDTOS)) {
            // 构建用户相关依赖属性
            List<Company> companies = companyMapper.selectAll();
            Map<Long, CompanyDTO> companyVOMap = new HashMap<>();
            for (Company company : companies) {
                companyVOMap.put(company.getId(), BeanUtil.copy(company, CompanyDTO.class));
            }
            List<Position> positions = positionMapper.selectAll();
            Map<Long, PositionDTO> positionHashMap = new HashMap<>();
            for (Position position : positions) {
                positionHashMap.put(position.getId(), BeanUtil.copy(position, PositionDTO.class));
            }
            List<Department> departments = departmentMapper.selectAll();
            Map<Long, DepartmentDTO> departmentDTOMap = new HashMap<>();
            for (Department department : departments) {
                departmentDTOMap.put(department.getId(), BeanUtil.copy(department, DepartmentDTO.class));
            }

            for (UserDTO userDTO : userDTOS) {
                if (!ObjectUtils.isEmpty(userDTO.getCompanyId())) {
                    userDTO.setCompany(companyVOMap.get(userDTO.getCompanyId()));
                }
                if (!ObjectUtils.isEmpty(userDTO.getPositionId())) {
                    userDTO.setPosition(positionHashMap.get(userDTO.getPositionId()));
                }
                if (!ObjectUtils.isEmpty(userDTO.getDepartmentId())) {
                    userDTO.setDepartment(departmentDTOMap.get(userDTO.getDepartmentId()));
                }
            }
        }
        // 转为为 CommonPage返回
        return cast2CommonPage(users, userDTOS);
    }
    @Override
    public RoleDTO queryUserResource(Long id) {
        /**
         * 取得用户所有的角色id
         */
        Role role = roleMapper.selectByPrimaryKey(id);
        Example example = new Example(RoleResource.class);
        example.selectProperties("resourceId");
        example.createCriteria().andEqualTo("roleId", id);
        List<RoleResource> roleResources = roleResourceMapper.selectByExample(example);
        Set<Long> idSet = new HashSet<>();
        for (RoleResource roleResource : roleResources) {
            idSet.add(roleResource.getResourceId());
        }
        // 根据所有的角色id取得所有的资源
        if (!idSet.isEmpty()) {
            Example re = new Example(Resource.class);
            re.createCriteria().andIn("id", idSet);
            // 重复的要去除
            List<Resource> resources = resourceMapper.selectByExample(re);
            resources=resources.stream().distinct().collect(Collectors.toList());
            List<ResourceDTO> resourceDTOS = BeanUtil.copyList(resources, ResourceDTO.class);
            RoleDTO copy = BeanUtil.copy(role, RoleDTO.class);
            copy.setResourceDTOS(resourceDTOS);
            return copy;
        } else {
            return new RoleDTO();
        }
    }
    @Override
    public RoleCompanyVO queryRoleCompanyById(@NotNull Long id) {
        Example example = new Example(RoleCompany.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("roleId", id);
        // 获取对应角色id的 角色-授权公司 列表
        List<RoleCompany> roleCompanyList = roleCompanyMapper.selectByExample(example);
        List<Long> authCompanyIds = roleCompanyList.stream().map(RoleCompany::getAuthCompanyId)
                .collect(Collectors.toList());
        // 角色所属于的公司
        RoleCompanyVO roleCompanyVO = new RoleCompanyVO();
        roleCompanyVO.setRoleId(id);
        roleCompanyVO.setAuthCompanyIds(authCompanyIds);
        return roleCompanyVO;
    }
    @Override
    public Boolean modifyRoleCompany(@NotNull @Valid RoleCompanyDTO roleCompanyDTO) {
        List<Long> roleIds = roleCompanyDTO.getRoleIds();
        for (Long roleId : roleIds) {
            Example selectExample = new Example(RoleCompany.class);
            Example.Criteria selectCriteria = selectExample.createCriteria();
            selectCriteria.andEqualTo("roleId", roleId);
            // 获取数据库 原有的(old) 对应角色id的 角色-授权公司 id列表
            List<RoleCompany> roleCompanyList = roleCompanyMapper.selectByExample(selectExample);
            List<Long> oldAuthCompanyIdList = roleCompanyList.stream()
                    .map(RoleCompany::getAuthCompanyId).collect(Collectors.toList());
            // 获取前端传来的 最新的(new) 角色id的 角色-授权公司 id列表
            List<Long> newAuthCompanyIdList = roleCompanyDTO.getAuthCompanyIds();

            // 旧的id列表去掉已经在新的id列表的那部分（去掉交集）是准备要删除的
            List<Long> toDelete = oldAuthCompanyIdList.stream()
                    .filter(id -> !newAuthCompanyIdList.contains(id)).collect(Collectors.toList());
            // 新的id列表去掉在旧的id列表的那部分（去掉交集）是准备要添加的
            List<Long> toInsert = newAuthCompanyIdList.stream()
                    .filter(id -> !oldAuthCompanyIdList.contains(id)).collect(Collectors.toList());

            if (!toDelete.isEmpty()) {
                Example deleteExample = new Example(RoleCompany.class);
                Example.Criteria deleteCriteria = deleteExample.createCriteria();
                deleteCriteria.andEqualTo("roleId", roleId).andIn("authCompanyId", toDelete);
                roleCompanyMapper.deleteByExample(deleteExample);
            }

            List<RoleCompany> insertRoleCompanyList = new ArrayList<>();
            toInsert.forEach(authCompanyId -> {
                RoleCompany roleCompany = new RoleCompany();
                roleCompany.setRoleId(roleId);
                roleCompany.setAuthCompanyId(authCompanyId);
                initEntity(roleCompany);
                insertRoleCompanyList.add(roleCompany);
            });
            if (!insertRoleCompanyList.isEmpty()) {
                roleCompanyMapper.insertList(insertRoleCompanyList);
            }
        }
        return true;
    }

    /**
     * 初始化对象公共属性
     * @param entity
     */
    private void initEntity(TenantBaseEntity entity) {
        entity.setId(idGenerator.snowflakeId());
        baseDataStuff4Add(entity);
        baseDataStuffCommonPros(entity);
        entity.setStatus(EntityConsts.INITIAL_STATUS);
        entity.setVersion(EntityConsts.INITIAL_VERSION);
    }

    /***********************************************************************************
     * 以下代码 2023-04-20重构 角色管理模块代码 增加 缓存更新 优化了批量插入的效率
     */
    /**
     *  删除角色的所有的资源
     * @param roleIds  角色id列表
     * @return true成功 false失败  如果成功外部调用删除缓存
     */
    private  boolean removeRolesResources(List<Long> roleIds){
        // 进行角色分配 采用先删除后插入的策略
        Example example=new Example(RoleResource.class);
        example.createCriteria().andIn("roleId",roleIds);
        return roleResourceMapper.deleteByExample(example)>0;
    }

    /**
     *  批量插入角色资源关系
     * @param roleIds  角色列表
     * @param resources 角色所拥有的资源的列表
     * @return true成功 false失败
     */
    private boolean batchInsertRolesResources(List<Long> roleIds,List<Long> resources){
        Set<RoleResource> roleResourceSet=new HashSet<>();
        // 构建插入数据 且去重复 依据 角色id，资源id，租户
        for (Long roleId : roleIds){
            resources.stream().forEach(resourceId->{
                RoleResource roleResource=new RoleResource();
                roleResource.setRoleId(roleId);
                roleResource.setId(idGenerator.snowflakeId());
                roleResource.setResourceId(resourceId);
                baseDataStuff4Add(roleResource);
                roleResource.setStatus(EntityConsts.INITIAL_STATUS);
                roleResource.setVersion(EntityConsts.INITIAL_VERSION);
                roleResourceSet.add(roleResource);
            });
        }
        List<RoleResource> roleResourceList= CollectionUtils.arrayToList(roleResourceSet.toArray());
        // 批量插入避免数据库插入堵塞
        int times=roleResourceList.size()/100;
        int total=0;
            for(int i=0;i<times;i++){
                total+=roleResourceMapper.batchInsert(roleResourceList.subList(i*100,(i+1)*100));
            }
            if(roleResourceList.size()>total){
                total+=roleResourceMapper.batchInsert(roleResourceList.subList(total,roleResourceList.size()));
            }
            return  roleResourceList.size()==total;
    }
}